﻿namespace StochasticSimulation.ChemicalReaction.ReactionGraph

open StochasticSimulation.ChemicalReaction.ChemicalReaction

type Node<'T> =
    int (* node identifier *) *
    'T (* node data *)
 
type Edge<'T> =
    Node<'T> * Node<'T> (* from -> to *)
 
type Connection<'T> =
    Node<'T> * Edge<'T> list

 
type Graph( reactions : Reaction list ) =
    let inputNodes : Node<Reaction> list =
        reactions |> List.mapi (fun i nd -> (i,nd) )
    let toEdge sink source : Edge<Reaction>=
        (sink,source)
//    let connections : Connection<Reaction> list = 
//        let affects (n:Node<Reaction>) = inputNodes |> List.filter ( fun nn -> (snd n).Affects (snd nn))
//        inputNodes |> List.map (fun n -> (n, List.map ( fun nn -> toEdge n nn) (affects n) ) )
    let connections : Connection<Reaction> list = 
        let affects (n:Node<Reaction>) = 
            (snd n).Affects |> List.collect ( fun a -> (inputNodes |> List.filter ( fun i -> List.exists (fun d -> d = a ) (snd i).Depends ) )  )
        inputNodes |> List.map (fun n -> (n, List.map ( fun nn -> toEdge n nn) (affects n) ) )  
        
    member this.Connections() =
        connections

    member this.GetAffected( r : Reaction ) =
        let edges = connections |> List.pick (fun c -> if (snd (fst c)) = r then Some(snd c) else None )
        edges |> List.map (fun e -> snd (snd e) ) 
 